package com.link.base.wechat.authweb.service;

import com.alibaba.fastjson.JSONObject;
import com.link.base.wechat.authweb.model.AuthWeb;
import com.link.base.wechat.authweb.util.WxAuthWebUtil;
import com.link.base.wechat.thirdparty.util.WxThirdPartyUtil;
import com.link.base.wechat.wxlog.model.WxLogModule;
import com.link.base.wechat.wxlog.service.WxLogService;
import com.link.base.wechat.wxplatform.model.WxPlatform;
import com.link.base.wechat.wxplatform.service.WxPlatformService;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.RedisUtil;
import com.link.core.util.StringUtils;
import com.link.base.core.basic.util.YmlConstants;
import com.link.core.util.redisclient.LinkRedisClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 微信网页授权
 *
 * @author ouyangzhenqiang
 * @date 2019/03/10 23:39;
 */
@Service
public class AuthWebServiceImpl implements AuthWebService {
    /**
     * 公众号模式判断
     */
    private static final String Y_STR = "Y";
    /**
     * 判断链接中是否有问号
     */
    private static final String QUESTION_MARK = "?";
    /**
     * 授权模式scope，此为snsapi_base
     */
    private static final String SCOPE_BASE = "base";
    /**
     * 额外控制返回给前端的链接参数是code，还是code转换的openid
     */
    private static final String AUTH_TYPE_CODE = "code";

    @Resource
    private WxPlatformService wxPlatformService;
    @Resource
    private WxLogService wxLogService;

    @Override
    public String generateAuthWebUrl(String wxAppId, String scope, String crmRedisKey) throws Exception {
        String authWebUrl;
        String redirectUri = YmlConstants.getWxComponentAuthRedirectUrl() + "/link/wxAuthWeb/receiveCode";
        WxPlatform wxPlatform = checkWxPlatform(wxAppId);
        // 默认静默授权
        String snsapiScope = SCOPE_BASE.equals(scope) ? "snsapi_base" : "snsapi_userinfo";
        String isDevMode = wxPlatform.getIs_dev_mode();
        if (Y_STR.equals(isDevMode)) {
            authWebUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?"
                + "appid=" + wxAppId + "&redirect_uri=" + redirectUri + "&response_type=code"
                + "&scope=" + snsapiScope + "&state=" + crmRedisKey + "#wechat_redirect";
        } else {
            authWebUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?"
                + "appid=" + wxAppId + "&redirect_uri=" + redirectUri + "&response_type=code"
                + "&scope=" + snsapiScope + "&state=" + crmRedisKey + "&component_appid=" + YmlConstants.getWxComponentAppId() + "#wechat_redirect";
        }
        wxLogService.log(WxLogModule.wxLogOauth2, "网页授权",
            "生成授权链接 => " + authWebUrl, wxAppId, wxPlatform.getCorpid());
        return authWebUrl;
    }

    @Override
    public String dealCodeReturnRedirectUrl(String code, String crmRedisKey) throws Exception {
        LinkRedisClient j = RedisUtil.getJedis();
        String redirectUrl;
        try {
            String wxAppId = j.hget(crmRedisKey, "wxAppId");
            redirectUrl = j.hget(crmRedisKey, "redirectUrl");
            String authType = j.hget(crmRedisKey, "auth_type");
            String param;
            // 默认id模式
            if (AUTH_TYPE_CODE.equals(authType)) {
                param = "code=" + code;
            } else {
                AuthWeb authWeb = getUserByCode(code, wxAppId);
                param = "openid=" + authWeb.getOpenid() + "&unionid=" + authWeb.getUnionid();
            }
            if (redirectUrl.contains(QUESTION_MARK)) {
                redirectUrl = redirectUrl + "&" + param;
            } else {
                redirectUrl = redirectUrl + "?" + param;
            }
        } finally {
            j.del(crmRedisKey);
            RedisUtil.returnResource(j);
        }
        return redirectUrl;
    }

    @Override
    public AuthWeb getUserByCode(String code, String wxAppId) throws Exception {
        WxPlatform wxPlatform = checkWxPlatform(wxAppId);
        String isDevMode = wxPlatform.getIs_dev_mode();
        JSONObject result;
        if (Y_STR.equals(isDevMode)) {
            result = WxAuthWebUtil.getUserInfoByDevCode(code, wxAppId, wxPlatform.getWx_app_secret());
        } else {
            result = WxAuthWebUtil.getUserInfoByComponentCode(code, wxAppId,
                YmlConstants.getWxComponentAppId(), WxThirdPartyUtil.getComponentAccessToken());
        }
        AuthWeb authWeb = new AuthWeb();
        authWeb.setAccess_token(result.getString("access_token"));
        authWeb.setRefresh_token(result.getString("refresh_token"));
        authWeb.setOpenid(result.getString("openid"));
        authWeb.setUnionid(result.getString("unionid"));
        return authWeb;
    }

    /**
     * 获取公众号信息
     *
     * @author ouyangzhenqiang
     * @date 2019/03/11 01:31
     * @param wxAppId 微信公众号应用Id
     */
    private WxPlatform checkWxPlatform(String wxAppId) throws Exception {
        if (StringUtils.isBlank(wxAppId)) {
            throw new ServiceException("AUTHWEB-002");
        }
        WxPlatform wxPlatform = wxPlatformService.getWxPlatformByAppId(wxAppId);
        if (wxPlatform == null) {
            throw new ServiceException("AUTHWEB-004", wxAppId);
        }
        return wxPlatform;
    }
}
